Graph valid tree¶
Time: O(|V|+|E|); Space: O(|V|+|E|); medium
Given N nodes labeled from 0 to N - 1 and a list of undirected edges (each edge is a pair of nodes), write a function to check whether these edges make up a valid tree.
You can assume that no duplicate edges will appear in edges. Since all edges are undirected, [0, 1] is the same as [1, 0] and thus will not appear together in edges.
Have you met this question in a real interview?
Example 1:
Input: n = 5, edges = [[0, 1], [0, 2], [0, 3], [1, 4]]
Output: True
Example 2:
Input: n = 5, edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]]
Output: False
[1]:
from collections import defaultdict, deque
class Solution1:
"""
BFS solution. Same complexity but faster version.
Time: O(|V| + |E|)
Space: O(|V| + |E|)
"""
def validTree(self, n, edges):
"""
:type n: int
:type edges: List[List[int]]
:rtype: bool
"""
if len(edges) != n - 1: # Check number of edges.
return False
elif n == 1:
return True
# A structure to track each node's [visited_from, neighbors]
visited_from = [-1] * n
neighbors = defaultdict(list)
for u, v in edges:
neighbors[u].append(v)
neighbors[v].append(u)
if len(neighbors) != n: # Check number of nodes.
return False
# BFS to check whether the graph is valid tree.
visited = {}
q = deque([0])
while q:
i = q.popleft()
visited[i] = True
for node in neighbors[i]:
if node != visited_from[i]:
if node in visited:
return False
else:
visited[node] = True
visited_from[node] = i
q.append(node)
return len(visited) == n
[3]:
s = Solution1()
n = 5
edges = [[0, 1], [0, 2], [0, 3], [1, 4]]
assert s.validTree(n, edges) == True
n = 5
edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]]
assert s.validTree(n, edges) == False
[4]:
from collections import defaultdict, deque
class Solution2:
'''
BFS solution.
Time: O(|V| + |E|)
Space: O(|V| + |E|)
'''
# @param {integer} n
# @param {integer[][]} edges
# @return {boolean}
def validTree(self, n, edges):
# A structure to track each node's [visited_from, neighbors]
visited_from = [-1] * n
neighbors = defaultdict(list)
for u, v in edges:
neighbors[u].append(v)
neighbors[v].append(u)
# BFS to check whether the graph is valid tree.
visited = {}
q = deque([0])
while q:
i = q.popleft()
visited[i] = True
for node in neighbors[i]:
if node != visited_from[i]:
if node in visited:
return False
else:
visited[node] = True
visited_from[node] = i
q.append(node)
return len(visited) == n
[5]:
s = Solution2()
n = 5
edges = [[0, 1], [0, 2], [0, 3], [1, 4]]
assert s.validTree(n, edges) == True
n = 5
edges = [[0, 1], [1, 2], [2, 3], [1, 3], [1, 4]]
assert s.validTree(n, edges) == False